if (!dojo._hasResource["dojo.i18n"]) { //_hasResource checks added by build. Do not use _hasResource directly in your code.
    dojo._hasResource["dojo.i18n"] = true;
    dojo.provide("dojo.i18n");

    /*=====
     dojo.i18n = {
     // summary: Utility classes to enable loading of resources for internationalization (i18n)
     };
     =====*/

    dojo.i18n.getLocalization =
    function(/*String*/packageName, /*String*/bundleName, /*String?*/locale) {
        //	summary:
        //		Returns an Object containing the localization for a given resource
        //		bundle in a package, matching the specified locale.
        //	description:
        //		Returns a hash containing name/value pairs in its prototypesuch
        //		that values can be easily overridden.  Throws an exception if the
        //		bundle is not found.  Bundle must have already been loaded by
        //		`dojo.requireLocalization()` or by a build optimization step.  NOTE:
        //		try not to call this method as part of an object property
        //		definition (`var foo = { bar: dojo.i18n.getLocalization() }`).  In
        //		some loading situations, the bundle may not be available in time
        //		for the object definition.  Instead, call this method inside a
        //		function that is run after all modules load or the page loads (like
        //		in `dojo.addOnLoad()`), or in a widget lifecycle method.
        //	packageName:
        //		package which is associated with this resource
        //	bundleName:
        //		the base filename of the resource bundle (without the ".js" suffix)
        //	locale:
        //		the variant to load (optional).  By default, the locale defined by
        //		the host environment: dojo.locale

        locale = dojo.i18n.normalizeLocale(locale);

        // look for nearest locale match
        var elements = locale.split('-');
        var module = [packageName,"nls",bundleName].join('.');
        var bundle = dojo._loadedModules[module];
        if (bundle) {
            var localization;
            for (var i = elements.length; i > 0; i--) {
                var loc = elements.slice(0, i).join('_');
                if (bundle[loc]) {
                    localization = bundle[loc];
                    break;
                }
            }
            if (!localization) {
                localization = bundle.ROOT;
            }

            // make a singleton prototype so that the caller won't accidentally change the values globally
            if (localization) {
                var clazz = function() {
                };
                clazz.prototype = localization;
                return new clazz(); // Object
            }
        }

        throw new Error("Bundle not found: " + bundleName + " in " + packageName + " , locale=" +
                        locale);
    };

    dojo.i18n.normalizeLocale = function(/*String?*/locale) {
        //	summary:
        //		Returns canonical form of locale, as used by Dojo.
        //
        //  description:
        //		All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
        //		If no locale is specified, the dojo.locale is returned.  dojo.locale is defined by
        //		the user agent's locale unless overridden by djConfig.

        var result = locale ? locale.toLowerCase() : dojo.locale;
        if (result == "root") {
            result = "ROOT";
        }
        return result; // String
    };

    dojo.i18n._requireLocalization =
    function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/
                       availableFlatLocales) {
        //	summary:
        //		See dojo.requireLocalization()
        //	description:
        // 		Called by the bootstrap, but factored out so that it is only
        // 		included in the build when needed.

        var targetLocale = dojo.i18n.normalizeLocale(locale);
        var bundlePackage = [moduleName, "nls", bundleName].join(".");
        // NOTE:
        //		When loading these resources, the packaging does not match what is
        //		on disk.  This is an implementation detail, as this is just a
        //		private data structure to hold the loaded resources.  e.g.
        //		`tests/hello/nls/en-us/salutations.js` is loaded as the object
        //		`tests.hello.nls.salutations.en_us={...}` The structure on disk is
        //		intended to be most convenient for developers and translators, but
        //		in memory it is more logical and efficient to store in a different
        //		order.  Locales cannot use dashes, since the resulting path will
        //		not evaluate as valid JS, so we translate them to underscores.

        //Find the best-match locale to load if we have available flat locales.
        var bestLocale = "";
        if (availableFlatLocales) {
            var flatLocales = availableFlatLocales.split(",");
            for (var i = 0; i < flatLocales.length; i++) {
                //Locale must match from start of string.
                if (targetLocale.indexOf(flatLocales[i]) == 0) {
                    if (flatLocales[i].length > bestLocale.length) {
                        bestLocale = flatLocales[i];
                    }
                }
            }
            if (!bestLocale) {
                bestLocale = "ROOT";
            }
        }

        //See if the desired locale is already loaded.
        var tempLocale = availableFlatLocales ? bestLocale : targetLocale;
        var bundle = dojo._loadedModules[bundlePackage];
        var localizedBundle = null;
        if (bundle) {
            if (dojo.config.localizationComplete && bundle._built) {
                return;
            }
            var jsLoc = tempLocale.replace(/-/g, '_');
            var translationPackage = bundlePackage + "." + jsLoc;
            localizedBundle = dojo._loadedModules[translationPackage];
        }

        if (!localizedBundle) {
            bundle = dojo["provide"](bundlePackage);
            var syms = dojo._getModuleSymbols(moduleName);
            var modpath = syms.concat("nls").join("/");
            var parent;

            dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc) {
                var jsLoc = loc.replace(/-/g, '_');
                var translationPackage = bundlePackage + "." + jsLoc;
                var loaded = false;
                if (!dojo._loadedModules[translationPackage]) {
                    // Mark loaded whether it's found or not, so that further load attempts will not be made
                    dojo["provide"](translationPackage);
                    var module = [modpath];
                    if (loc != "ROOT") {
                        module.push(loc);
                    }
                    module.push(bundleName);
                    var filespec = module.join("/") + '.js';
                    loaded = dojo._loadPath(filespec, null, function(hash) {
                        // Use singleton with prototype to point to parent bundle, then mix-in result from loadPath
                        var clazz = function() {
                        };
                        clazz.prototype = parent;
                        bundle[jsLoc] = new clazz();
                        for (var j in hash) {
                            bundle[jsLoc][j] = hash[j];
                        }
                    });
                } else {
                    loaded = true;
                }
                if (loaded && bundle[jsLoc]) {
                    parent = bundle[jsLoc];
                } else {
                    bundle[jsLoc] = parent;
                }

                if (availableFlatLocales) {
                    //Stop the locale path searching if we know the availableFlatLocales, since
                    //the first call to this function will load the only bundle that is needed.
                    return true;
                }
            });
        }

        //Save the best locale bundle as the target locale bundle when we know the
        //the available bundles.
        if (availableFlatLocales && targetLocale != bestLocale) {
            bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')];
        }
    };

    (function() {
        // If other locales are used, dojo.requireLocalization should load them as
        // well, by default.
        //
        // Override dojo.requireLocalization to do load the default bundle, then
        // iterate through the extraLocale list and load those translations as
        // well, unless a particular locale was requested.

        var extra = dojo.config.extraLocale;
        if (extra) {
            if (!extra instanceof Array) {
                extra = [extra];
            }

            var req = dojo.i18n._requireLocalization;
            dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales) {
                req(m, b, locale, availableFlatLocales);
                if (locale) {
                    return;
                }
                for (var i = 0; i < extra.length; i++) {
                    req(m, b, extra[i], availableFlatLocales);
                }
            };
        }
    })();

    dojo.i18n._searchLocalePath =
    function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc) {
        //	summary:
        //		A helper method to assist in searching for locale-based resources.
        //		Will iterate through the variants of a particular locale, either up
        //		or down, executing a callback function.  For example, "en-us" and
        //		true will try "en-us" followed by "en" and finally "ROOT".

        locale = dojo.i18n.normalizeLocale(locale);

        var elements = locale.split('-');
        var searchlist = [];
        for (var i = elements.length; i > 0; i--) {
            searchlist.push(elements.slice(0, i).join('-'));
        }
        searchlist.push(false);
        if (down) {
            searchlist.reverse();
        }

        for (var j = searchlist.length - 1; j >= 0; j--) {
            var loc = searchlist[j] || "ROOT";
            var stop = searchFunc(loc);
            if (stop) {
                break;
            }
        }
    };

    dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated) {
        //	summary:
        //		Load built, flattened resource bundles, if available for all
        //		locales used in the page. Only called by built layer files.

        function preload(locale) {
            locale = dojo.i18n.normalizeLocale(locale);
            dojo.i18n._searchLocalePath(locale, true, function(loc) {
                for (var i = 0; i < localesGenerated.length; i++) {
                    if (localesGenerated[i] == loc) {
                        dojo["require"](bundlePrefix + "_" + loc);
                        return true; // Boolean
                    }
                }
                return false; // Boolean
            });
        }
        preload();
        var extra = dojo.config.extraLocale || [];
        for (var i = 0; i < extra.length; i++) {
            preload(extra[i]);
        }
    };

}
